package com.click.app.webapp.action;

import com.click.app.model.Product;
import com.click.app.model.EntryProduct;
import com.click.app.model.EntryProductDetail;
import com.click.app.model.StorageProduct;
import com.click.app.service.ProductManager;
import com.click.app.service.EntryProductDetailManager;
import com.click.app.service.EntryProductManager;
import com.click.app.service.StorageProductManager;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;

/**
 * @author Joel Chuca
 */
public class EntryProductDetailAction extends BaseAction {

    private ProductManager productManager;
    private EntryProductDetailManager entryProductDetailManager;
    private StorageProductManager storageProductManager;
    private EntryProductManager entryProductManager;
    private EntryProduct entryProduct;
    private List<Product> products;
    private List<EntryProductDetail> entryProductDetails;
    private EntryProductDetail entryProductDetail;
    private Product product;
    private Long id;
    private Long idEntryProduct;
    private List<EntryProduct> entryProductList;
    private HashMap reportParams;
    private String formatNumberTooltip;
    private List<StorageProduct> storageProductList;
    private String quantity;
    private String unitPrice;
    private String sellPrice;
    private float quantityUsed;
    private StorageProduct storageProduct;

    public void setProductManager(ProductManager productManager) {
        this.productManager = productManager;
    }

    public void setEntryProductDetailManager(EntryProductDetailManager entryProductDetailManager) {
        this.entryProductDetailManager = entryProductDetailManager;
    }

    public void setEntryProductManager(EntryProductManager entryProductManager) {
        this.entryProductManager = entryProductManager;
    }

    public void setStorageProductManager(StorageProductManager storageProductManager) {
        this.storageProductManager = storageProductManager;
    }

    public List getProducts() {
        return products;
    }

    public List<EntryProductDetail> getEntryProductDetails() {
        return entryProductDetails;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    public EntryProductDetail getEntryProductDetail() {
        return entryProductDetail;
    }

    public void setEntryProductDetail(EntryProductDetail entryProductDetail) {
        this.entryProductDetail = entryProductDetail;
    }

    public Long getIdEntryProduct() {
        return idEntryProduct;
    }

    public void setIdEntryProduct(Long idEntryProduct) {
        this.idEntryProduct = idEntryProduct;
    }

    public EntryProduct getEntryProduct() {
        return entryProduct;
    }

    public String getFormatNumberTooltip() {
        return formatNumberTooltip;
    }

    public String list() {
        if (idEntryProduct != null) {
            entryProduct = entryProductManager.get(idEntryProduct);
            System.out.println("");

            getSession().setAttribute("entryProduct", entryProduct);
        } else {
            entryProduct = ((EntryProduct) getSession().getAttribute("entryProduct"));
        }
        if (entryProduct != null) {
            entryProductDetails = entryProductManager.get(entryProduct.getId()).getEntryProductDetails();
        } else {
            System.out.println("entryProduct is null");
            return ERROR;
        }
        System.out.println("listando...");
        System.out.println("list: " + entryProduct.getEntryProductDetails());
        System.out.println("list2: " + entryProductDetails);


        return SUCCESS;
    }

    public String edit() {
        System.out.println(" EntryProductDetailAction -> edit() ");

        String ps = ((EntryProduct) getSession().getAttribute("entryProduct")).getSupplier().getName();
        String pd = ((EntryProduct) getSession().getAttribute("entryProduct")).getDate().toString();
        String ptp = ((EntryProduct) getSession().getAttribute("entryProduct")).getTotalPrice().toString();
        getSession().setAttribute("ps", ps);
        getSession().setAttribute("pd", pd);
        getSession().setAttribute("ptp", ptp);

        products = productManager.getAll();
        if (id != null) {
            entryProductDetail = entryProductDetailManager.get(id);
            product = entryProductDetail.getProduct();
            quantity = entryProductDetail.getQuantity().toString();
            unitPrice = entryProductDetail.getUnitPrice().toString();
            sellPrice = entryProductDetail.getSellPrice().toString();



        } else {
            entryProductDetail = ((EntryProductDetail) getSession().getAttribute("entryProductDetail"));
            // verify if was sended to reload
            if (entryProductDetail != null) {
                product = ((Product) getSession().getAttribute("product"));
            } else {
                entryProductDetail = new EntryProductDetail();
            }
        }
        formatNumberTooltip = getText("formatNumber.tooltip");
        System.out.println(" EntryProductDetailAction -> end edit() ");

        return SUCCESS;
    }

    public boolean validationPasses() {
        Float aux = 0.0f;
        Integer aux2 = 0;
        Float aux3 = 0.0f;
        boolean vp = true;
        if (getQuantity() == null || getQuantity().matches("")) {
            errorMessage("Required field, quantity.");
            vp = false;
        }
        if (getUnitPrice() == null || getUnitPrice().matches("")) {
            errorMessage("Required field, unit price.");
            vp = false;
        }
        if (getSellPrice() == null || getSellPrice().matches("")) {
            errorMessage("Required field, sell price.");
            vp = false;
        }


        try {
            if (getUnitPrice() != null && !getUnitPrice().matches("")) {
                aux = Float.parseFloat(getUnitPrice());
            }
            if (aux < 0) {
                errorMessage("Negative number[unit price].");
                vp = false;
            }


        } catch (Exception e) {
            errorMessage("Incorrect number format[unit price].");
            vp = false;
        }

        try {
            if (getQuantity() != null && !getQuantity().matches("")) {
                aux2 = Integer.parseInt(getQuantity());
            }
            if (aux2 < 0) {
                errorMessage("Negative number[quantity].");
                vp = false;
            }
        } catch (Exception e) {
            errorMessage("Incorrect number format[quantity].");
            vp = false;
        }

        return vp;
    }

    public String save() {
        System.out.println("EntryProductDetailAction -> save()");
        // get datas of product entity selected
        entryProductDetail.setQuantity(Integer.parseInt(getQuantity()));
        entryProductDetail.setUnitPrice(Float.parseFloat(getUnitPrice()));
        entryProductDetail.setSellPrice(Float.parseFloat(getSellPrice()));
        System.out.println("sellprice: " + entryProductDetail.getSellPrice());
        getSession().setAttribute("entryProductDetail", entryProductDetail);
        product = productManager.get(product.getId());
        getSession().setAttribute("product", product);
        System.out.println("EntryProductDetailAction -> end save()");
        return "reload";
    }

    public String doneProductCutterUsed() {

        return SUCCESS;
    }

    public String saveButton() throws Exception {

        System.out.println("PurhcseDetailAction -> saveButton()");
        if (!validationPasses()) {
            System.out.println("validacion no paso");
            return "reload";
        }
        System.out.println("se hizo la pera la validacion");

        if (cancel != null) {
            return CANCEL;
        }

        if (delete != null) {
            return delete();
        }

        Enumeration<String> en = getRequest().getParameterNames();
        while (en.hasMoreElements()) {
            en.nextElement();
        }

        boolean isNew = false;
        isNew = (entryProductDetail.getId() == null);
        float oldPrice = 0;
        if (!isNew) {
            // update storageProduct if product or entryProductDetail quantity had been changeds
            EntryProductDetail entryProductDetailOld = entryProductDetailManager.get(entryProductDetail.getId());
            StorageProduct storageOld = productManager.get(entryProductDetailOld.getProduct().getId()).getStorageProduct();
            Integer quantityOld = entryProductDetailOld.getQuantity();
            storageOld.decrementStok(quantityOld);
            storageOld = storageProductManager.save(storageOld);
            oldPrice = entryProductDetailOld.getTotalPrice();
        }

        product = productManager.get(product.getId());
        entryProduct = (EntryProduct) getSession().getAttribute("entryProduct");

        entryProductDetail.setProduct(product);
        entryProductDetail.setEntryProduct(entryProduct);
        entryProductDetail.setQuantity(Integer.parseInt(getRequest().getParameter("quantity")));
        entryProductDetail.setUnitPrice(Float.parseFloat(getRequest().getParameter("unitPrice")));
        entryProductDetail.setSellPrice(Float.parseFloat(getRequest().getParameter("sellPrice")));
        entryProductDetail.setDiscountXfail(0.0f);
        entryProductDetail.setCurrentQuantity(entryProductDetail.getQuantity());
        entryProductDetail.setQuantityFail(0.0f);
        entryProductDetail.setDeleted(true);

        entryProductDetail.setTotalPrice(entryProductDetail.getQuantity() * entryProductDetail.getUnitPrice());

        // update entryProduct
        if (isNew) {
            entryProduct.setTotalPrice(entryProduct.getTotalPrice() + entryProductDetail.getTotalPrice());
        } else {
            entryProduct.setTotalPrice(entryProduct.getTotalPrice() - oldPrice + (entryProductDetail.getQuantity() * entryProductDetail.getUnitPrice()));
        }
        entryProduct = entryProductManager.save(entryProduct);
        entryProductDetail = entryProductDetailManager.save(entryProductDetail);

        // update storageProduct
        StorageProduct storageProduct = product.getStorageProduct();
        storageProduct.incrementStok(entryProductDetail.getCurrentQuantity());
        storageProduct = storageProductManager.save(storageProduct);

        //clean
        getSession().setAttribute("entryProductDetail", null);
        getSession().setAttribute("product", null);

        if (isNew) {
            saveMessage(getText("entryProductDetail.added"));
            return SUCCESS;
        } else {
            saveMessage(getText("entryProductDetail.updated"));
            return INPUT;
        }

    }
    /*
    public String addProductCutterUsed(){
    System.out.println("addProductCutterUsed() ");
    List<Product> products = entryProductDetailManager.findAllNoPackageDetail();
    storageProductList = new ArrayList<StorageProduct>();
    for (Iterator<Product> it = products.iterator(); it.hasNext();) {
    Product product = it.next();
    storageProductList.addAll(storageProductManager.findByIdProductNoCero(product.getId()));
    }
    cutProcess = cutProcessManager.get((Long)getSession().getAttribute("idCutProcess"));
    System.out.println("end addProductCutterUsed() ");
    return SUCCESS;
    }

    public String deleteProductUsed(){
    System.out.println("EntryProductDetailAction -> deleteProductUsed() ");
    entryProductDetailCutProcess = entryProductDetailCutProcessManager.get(id);
    cutProcess = entryProductDetailCutProcess.getCutProcess();
    entryProductDetail = entryProductDetailCutProcess.getEntryProductDetail();
    entryProductDetail.setCurrentQuantity( entryProductDetail.getCurrentQuantity() + entryProductDetailCutProcess.getQuantity() );

    List<StorageProduct> storageProductList = storageProductManager.findByIdProduct(entryProductDetail.getProduct().getId());
    if(!storageProductList.isEmpty()){
    storageProduct = storageProductList.get(0);
    storageProduct.setStock(storageProduct.getStock() + entryProductDetailCutProcess.getQuantity());
    CutProcess cutProcess = entryProductDetailCutProcess.getCutProcess();
    cutProcess.setTotalAmountFail(cutProcess.getTotalAmountFail() + entryProductDetailCutProcess.getTotalAmountQuantityFail());

    BalanceEmployee balanceEmployee = cutProcess.getBalanceEmployee();
    balanceEmployee.setAmountWon(balanceEmployee.getAmountWon() + entryProductDetailCutProcess.getTotalAmountQuantityFail());

    balanceEmployeeManager.save(balanceEmployee);
    cutProcessManager.save(cutProcess);
    storageProductManager.save(storageProduct);
    entryProductDetailManager.save(entryProductDetail);
    entryProductDetailCutProcessManager.remove(id);
    }
    System.out.println("EntryProductDetailAction -> end deleteProductUsed() ");
    return SUCCESS;
    }
     */

    public StorageProduct getStorageProductByProduct(Product p) {
        StorageProduct resp = null;
        for (StorageProduct sp : storageProductManager.getAll()) {
            if (sp.getProduct().equals(p)) {
                resp = sp;
                return sp;
            }

        }
        return resp;
    }

    public String delete() {
        EntryProductDetail epd = entryProductDetailManager.get(entryProductDetail.getId());
        System.out.println("quantity to be decremented: "+epd.getCurrentQuantity());
        //entryProductDetail.setQuantity(Float.parseFloat(getRequest().getParameter("entryProductDetail.quantity")));
        entryProductDetailManager.remove(entryProductDetail.getId());
        // update entryProduct
        entryProduct = (EntryProduct) getSession().getAttribute("entryProduct");
        updateEntryProduct();
        
        // update storage product
        product = productManager.get(product.getId());
        StorageProduct sp = product.getStorageProduct();
        sp.decrementStok(epd.getCurrentQuantity());
        sp = storageProductManager.save(sp);

        saveMessage(getText("entryProductDetail.deleted"));

        return "delete";
    }

    public String finalizeEntryProduct() {
        getSession().setAttribute("entryProduct", null);
        getSession().setAttribute("entryProductDetail", null);
        getSession().setAttribute("packageDetail", null);
        getSession().setAttribute("product", null);
        return SUCCESS;
    }

    private void updateEntryProduct() {
        entryProductDetails = entryProductManager.get(entryProduct.getId()).getEntryProductDetails();
        entryProduct.setEntryProductDetails(entryProductDetails);
        Float priceTotal = new Float(0);
        for (EntryProductDetail pd : entryProductDetails) {
            priceTotal += pd.getTotalPrice();
        }
        entryProduct.setTotalPrice(priceTotal);
        entryProduct = entryProductManager.save(entryProduct);
    }

    public String help() {
        return SUCCESS;
    }
    /*
    public String generateJasperReport() {
    System.out.println("generando reporte ...");
    entryProduct = ((EntryProduct) getSession().getAttribute("entryProduct"));
    entryProductList = new ArrayList<EntryProduct>();
    entryProductList.add(entryProduct);

    String pathSubReport = getRequest().getSession().getServletContext().getRealPath("/reports/entryProductDetailSubReport.jasper");
    try {
    JasperReport subReport = (JasperReport) JRLoader.loadObject(new File(pathSubReport));
    reportParams = new HashMap();
    reportParams.put("subReport", subReport);
    reportParams.put("title", getText("entryProductDetail.title"));
    reportParams.put("supplierName", getText("entryProduct.supplier.fullName"));
    reportParams.put("entryProductDate", getText("entryProduct.date"));
    reportParams.put("coinName", getText("entryProduct.coin.name"));
    reportParams.put("totalPrice", getText("entryProduct.totalPrice"));
    reportParams.put("discount", getText("entryProduct.discount"));
    reportParams.put("realPrice", getText("entryProduct.realPrice"));
    reportParams.put("page", getText("display.page"));
    reportParams.put("sTitle", getText("entryProductDetailList.heading"));
    reportParams.put("sProduct", getText("product"));
    reportParams.put("sUnitMeasure", getText("entryProductDetail.product.unitMeasure"));
    reportParams.put("sQuantity", getText("entryProductDetail.quantity"));
    reportParams.put("sUnitPrice", getText("entryProductDetail.unitPrice"));
    reportParams.put("sTotalPrice", getText("entryProductDetail.totalPrice"));
    } catch (JRException ex) {
    Logger.getLogger(EntryProductDetailAction.class.getName()).log(Level.SEVERE, null, ex);
    }
    return SUCCESS;
    }
     */

    public List<EntryProduct> getEntryProductList() {
        return entryProductList;
    }

    public HashMap getReportParams() {
        return reportParams;
    }

    public List<StorageProduct> getStorageProductList() {
        return storageProductList;
    }

    public void setStorageProductList(List<StorageProduct> storageProductList) {
        this.storageProductList = storageProductList;
    }

    public float getQuantityUsed() {
        return quantityUsed;
    }

    public void setQuantityUsed(float quantityUsed) {

        this.quantityUsed = quantityUsed;
    }

    public StorageProduct getStorageProduct() {
        return storageProduct;
    }

    public void setStorageProduct(StorageProduct storageProduct) {
        this.storageProduct = storageProduct;
    }

    /**
     * @return the quantity
     */
    public String getQuantity() {
        return quantity;
    }

    /**
     * @param quantity the quantity to set
     */
    public void setQuantity(String quantity) {
        this.quantity = quantity;
    }

    /**
     * @return the unitPrice
     */
    public String getUnitPrice() {
        return unitPrice;
    }

    /**
     * @param unitPrice the unitPrice to set
     */
    public void setUnitPrice(String unitPrice) {
        this.unitPrice = unitPrice;
    }

    /**
     * @return the sellPrice
     */
    public String getSellPrice() {
        return sellPrice;
    }

    /**
     * @param sellPrice the sellPrice to set
     */
    public void setSellPrice(String sellPrice) {
        this.sellPrice = sellPrice;
    }
}
